module curves !points on the unit circle
   use precision
   private
   public curve
   public length, segment, create, destroy
   public x, y

   type curve
      private
      real(adequate), pointer:: x(:) => Null()
	  real(adequate), pointer:: y(:) => Null()
   end type curve

   interface create
      module procedure curve_create
   end interface create

   interface destroy
      module procedure curve_destroy
   end interface destroy

   interface length
      module procedure curve_length
   end interface length

   interface assignment(=)
      module procedure curve_set_curve
   end interface

contains

   function x(p)
   type(curve), intent(in):: p
   real(adequate):: x(size(p%x))
   x = p%x
   end function x

   function y(p)
   type(curve), intent(in):: p
   real(adequate):: y(size(p%y))
   y = p%y
   end function y

   function curve_length(p)
   type(curve), intent(in):: p
   real(adequate) r
   curve_length = size(p%x)
   end function curve_length

   subroutine curve_create(c, x, y)
   real(adequate), intent(in):: x(:), y(:)
   type(curve), intent(inout):: c
   if(size(x) /= size(y)) then
      stop "curve assignment: incorrect sizes"
   endif
   call curve_destroy(c)
   allocate(c%x(size(x)))
   allocate(c%y(size(y)))
   c%x = x
   c%y = y
   end subroutine curve_create

   subroutine curve_set_curve(p, q)
   type(curve), intent(inout):: p
   type(curve), intent(in):: q
   call curve_create (p, q%x, q%y)
   end subroutine curve_set_curve

   subroutine curve_destroy(p)
   type(curve), intent(inout):: p
   if(associated(p%x)) then
      deallocate(p%x)
	  deallocate(p%y)
   endif
   end subroutine curve_destroy


end module curves